package ay.shadow.openfein.client;


import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties;
import org.springframework.cloud.client.loadbalancer.Request;
import org.springframework.cloud.client.loadbalancer.Response;
import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer;
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import reactor.core.publisher.Mono;

import java.util.concurrent.CompletableFuture;

/**
 * 解决 http调用错误
 * block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-2
 * @Author: shadow
 * @Description: 自定义CustomBlockingLoadBalancerClient.java
 */
public class CustomBlockingLoadBalancerClient extends BlockingLoadBalancerClient {
    private final ReactiveLoadBalancer.Factory<ServiceInstance> loadBalancerClientFactory;

    public CustomBlockingLoadBalancerClient(LoadBalancerClientFactory loadBalancerClientFactory, LoadBalancerProperties properties) {
        super(loadBalancerClientFactory);
        this.loadBalancerClientFactory = loadBalancerClientFactory;
    }

    @Override
    public <T> ServiceInstance choose(String serviceId, Request<T> request) {
        ReactiveLoadBalancer<ServiceInstance> loadBalancer = loadBalancerClientFactory.getInstance(serviceId);
        if (loadBalancer == null) {
            return null;
        }
        CompletableFuture<Response<ServiceInstance>> f = CompletableFuture.supplyAsync(() -> {
            Response<ServiceInstance> loadBalancerResponse = Mono.from(loadBalancer.choose(request)).block();
            return loadBalancerResponse;
        });
        Response<ServiceInstance> loadBalancerResponse = null;


        try {
            loadBalancerResponse = f.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (loadBalancerResponse == null) {
            return null;
        }
        return loadBalancerResponse.getServer();
//        result = {NacosServiceInstance@13920}
//        serviceId = "shadow-stock"
//        instanceId = "192.168.1.19#8080#DEFAULT#STOCK@@shadow-stock"
//        host = "192.168.1.19"
//        port = 8080
//        secure = false
//        metadata = {HashMap@13924}  size = 6
//        "nacos.instanceId" -> "192.168.1.19#8080#DEFAULT#STOCK@@shadow-stock"
//        "nacos.weight" -> "1.0"
//        "nacos.cluster" -> "DEFAULT"
//        "nacos.ephemeral" -> "true"
//        "nacos.healthy" -> "true"
//        "preserved.register.source" -> "SPRING_CLOUD"
    }

}

